<?php

namespace app\admin\controller;

use app\admin\common\Constants;
use app\admin\traits\Backend;
use app\admin\traits\SelectCompany;
use think\Controller;
use think\Db;
use think\Session;

class Common extends Controller
{
    protected $company = null;

    protected $needSelectCompany = null;

    use SelectCompany;

    public function _initialize()
    {
        /**
         * 检查是否登录
         */
        if (!$this->check_login()) {
            $this->redirect(url('/admin/login/login'));
        }
        /**
         * 获取导航
         */
        $menu = $this->getMenu();
        $this->assign('menu', $menu);



        /**
         * 获取菜单树形结构
         * */
        $this->getMenuTree();

        /**
         * 获取配置分组
         * */
        $this->getConfigGroup();

        /**
         * 设置配置
         * */
        $this->setSystemConfig();

        /**
         * 检查权限
         */
        $this->checkUrlAuth();
        if (!is_null($this->needSelectCompany)) {
            $this->beforeActionList['__companyComponent__'] = $this->needSelectCompany;
        }
    }

    use Backend;

    /**
     * 获取导航数据
     * @return mixed
     */
    public function getMenu()
    {
        $userId = $this->getCurrentUser();
        $menu = cache($userId . 'admin_menu');
        if (!$menu) {
            //权限控制菜单显示
            $uid = $this->getCurrentUser();
            $auth_where = [];
            if ($uid > 1) {
                $user_rules_arr = $this->getUserAuthMenuId($uid);
                if ($user_rules_arr) $auth_where['id'] = ['IN', $user_rules_arr];
            } else if (empty($uid)) {
                $this->error('登录身份已过期，请重新登录', url('/admin/login/login'));
            }

            $menu = Db::name('menu')->field('id,icon,name,url')->where(['pid' => 0, 'status' => 1, 'is_show' => 1])->where($auth_where)->order('sort asc')->select();
            if ($menu) {
                foreach ($menu as &$v) {
                    $leftMenu = Db::name('menu')->field('id,icon,name,url')->where(['pid' => $v['id'], 'status' => 1, 'is_show' => 1])->where($auth_where)->order('sort asc')->select();
                    if ($leftMenu) {
                        foreach ($leftMenu as &$val) {
                            $sonMenu = Db::name('menu')->field('id,icon,name,url')->where(['pid' => $val['id'], 'status' => 1, 'is_show' => 1])->where($auth_where)->order('sort asc')->select();
                            $val['sonMenu'] = $sonMenu;
                            if (empty($val['url']) && count($sonMenu) > 0) $val['url'] = $sonMenu[0]['url'];
                        }
                    }
                    $v['leftMenu'] = $leftMenu;
                }
            }
            cache($userId . 'admin_menu', $menu);
        }

        return $menu;
    }

    function getCurrentUser()
    {
        $uid = session('id');
        return $uid;
    }

    protected function errorResponse($msg = '', $url = null, $data = '', $wait = 3, array $header = [])
    {
        $token = $this->request->token();
        if ($token) {
            $this->request->token($token, '', -$wait * 60);
            $header['token'] = $token;
        }
        $this->error($msg, $url, $data, $wait, $header);
    }

    /**
     * 后台菜单树形结构
     * */
    function getMenuTree()
    {
        $menu = cache('menu_tree');
        if (!$menu) {
            $menu = Db::name('menu')->field('id,name')->where(['pid' => 0, 'status' => 1])->order('sort asc')->select();
            if ($menu) {
                foreach ($menu as &$v) {
                    $groupMenu = Db::name('menu')->field('id,name')->where(['pid' => $v['id'], 'status' => 1])->order('sort asc')->select();
                    if ($groupMenu) {
                        foreach ($groupMenu as &$val) {
                            $list_menu = Db::name('menu')->field('id,name')->where(['pid' => $val['id'], 'status' => 1])->order('sort asc')->select();
                            if ($list_menu) {
                                foreach ($list_menu as &$value) {
                                    $do_menu = Db::name('menu')->field('id,name')->where(['pid' => $value['id'], 'status' => 1])->order('sort asc')->select();
                                    $value['do_menu'] = $do_menu;
                                }
                            }
                            $val['list_menu'] = $list_menu;
                        }
                    }
                    $v['group_menu'] = $groupMenu;
                }
            }

            cache('menu_tree', $menu);
        }

        return $menu;
    }

    /**
     * 获取配置分组
     * */
    public function getConfigGroup()
    {
        $configGroup = cache('configGroup');
        if (empty($configGroup)) {
            $configGroup = Db::name('config_group')->field('id,name,sort')->order('sort asc')->select();
            cache('configGroup', $configGroup);
        }

        return $configGroup;
    }

    /**
     * 设置配置
     * */
    public function setSystemConfig()
    {
        $config = cache('systemConfig');
        if (!$config) {
            $config = Db::name('config')->field('id,name,title,value,type,group_id')->order('sort asc')->select();
            if ($config) {
                foreach ($config as &$v) {
                    $v['output_value'] = $v['value'];
                    if ($v['type'] == 4) $v['output_value'] = preg_split("/(,|，|;|[\r\n])/", $v['output_value']);
                }
            }
            cache('systemConfig', $config);
        }
    }

    /**
     * 检查是否登录
     * @return bool
     */
    public function check_login()
    {
        if (!session('id', '') || !session('account', '')) {
            return false;
        }

        return true;
    }

    /**
     * 获取当前登录用户权限菜单id
     * */
    public function getUserAuthMenuId($uid)
    {
        $rules_list = Db::name('auth_group_access')->alias('a')->field('g.rules')->join('auth_group g', 'a.group_id = g.id')->where(['a.uid' => $uid, 'g.status' => 1])->select();
        if ($rules_list) {
            $new_rules = '';
            foreach ($rules_list as &$v) {
                if ($new_rules == '') {
                    $new_rules = $v['rules'];
                } else {
                    $new_rules = $new_rules . ',' . $v['rules'];
                }
            }
            //数组去重
            $new_rules_arr = array_unique(explode(',', $new_rules));
            return $new_rules_arr;
        } else {
            return [];
        }
    }

    /**
     * 检查某个url是否有权限访问
     * */
    public function checkUrlAuth()
    {

        $uid = session('id');
        if ($uid > 1) {
            $user_rules_arr = $this->getUserAuthMenuId($uid);
            $auth_where['id'] = ['IN', $user_rules_arr];

            $menu_list = Db::name('menu')->field('url')->where($auth_where)->select();
            if ($menu_list) {
                $visit_url = strtoupper(stripExtend(doRedirectUrl()));
                $auth_urls = strtoupper(implode(',', array_map(function ($item) {
                    return $item['url'];
                }, $menu_list)));
                if (!(strpos($auth_urls, $visit_url) !== false)) $this->error('您无权限访问');
            }
        } else if ($uid == 1) {
            $menu_list = Db::name('menu')->field('url')->select();
            $visit_url = strtoupper(stripExtend(doRedirectUrl()));
            $currentMenu = Db::name('menu')->where(['url' => strtolower($visit_url)])->find();
            $this->assign('currentMenu', $currentMenu);
            $auth_urls = strtoupper(implode(',', array_map(function ($item) {
                return $item['url'];
            }, $menu_list)));
        } else if (empty($uid)) {
            $this->redirect(url('/admin/login/login'));
        }
    }


    protected function checkToken()
    {
        $input = $this->request->param();
        $token = $input['__token__'];
        if (!checkToken($token)) {
            $this->errorResponse('表单错误，请刷新重新提交');
        }
    }

    /**
     * 获取当前登陆用户选择的企业
     * @return array|bool|\PDOStatement|string|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    protected function getCurrentCompany()
    {
        $company_id = session(Constants::$COMPANY_ID_KEY);
        if ($company_id) {
            $this->company = \app\admin\model\Company::where(['id' => $company_id])->find();
            if ($this->company) {
                $this->assign('company', $this->company);
                return $this->company;
            }
        }
        return false;
    }
}